<?php
/**
 * Created by PhpStorm.
 * User: poptser@foxmail.com
 * Date: 2018/3/16
 * Time: 14:52
 */
namespace App\Services\Sorting;
use App\Services\Orders\OrderService as Order;
use App\Services\SortingWeb\ToolService;
use App\Services\Warehouse\ConsignmentNoteService;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Mockery\Exception;

class RefundService{

    public $mainOrderService;          //主order service
    public $toolService;          //工具服务
    protected $ConsignmentNoteService;  //发货单服务

    public function __construct(Order $mainOrderService,ToolService $toolService,
                                ConsignmentNoteService $consignmentNoteService){
        $this->mainOrderService = $mainOrderService;
        $this->toolService = $toolService;
        $this->ConsignmentNoteService=$consignmentNoteService;

    }

    /**
     * 重组商品列表
     * Author:poptser@foxmail.com
     * @param $goodsList
     * @return array
     */
    public function buildGoodsList($goodsList){

        $newGoodsList = [];

        for ($refundType=1;$refundType<4;$refundType++){
            $newGoods['refundType'] = $refundType;
            foreach ($goodsList as $value){
                if($value['refund_type_select']==$refundType){
                    $newGoods['goodsList'][] = $value;
                }
            }
            if(!empty($newGoods['goodsList'])){
                $newGoodsList[] = $newGoods;
            }
            unset($newGoods);
        }

        return $newGoodsList;

    }


    /**
     * 订单退货
     * Author:poptser@foxmail.com
     * @param $orderId      //订单ID
     * @param $goodsList    //商品列表 goods_sn商品货号 rec_id商品表唯一 num操作数
     * @param $refundType   //退款类型 1缺货 2次品 3退货
     * @param $shippingFee  //是否退运费
     * @param $remark       //备注
     * @param $userId       //备注
     * @param $wid       //备注
     * @param $refundTypeClass       //是否问题单
     * @param $workType       //工单类型
     * @return mixed
     */
    public function refundGoods($orderId, $goodsList,$refundType, $shippingFee = false,
                                $remark,$userId,$wid,$refundTypeClass,$workType){
        //order_id订单ID goods_sn商品货号 rec_id商品表唯一 num操作数 refundType退款类型
        //return $goodsList;
        //return $goodsList;
        $orderField = ['order_id','order_sn','order_status','shipping_status','pay_status',
            'pay_id','pay_name','is_refund_freight','batch_no','shipping_fee'];

        $orderInfo = $this->mainOrderService->getOrderById($orderId,$orderField);

        //验证运费选项
        if($shippingFee&&$orderInfo['is_refund_freight']>0){
            return "错误：订单已退运费";
        }
        $goodsListNow = $this->mainOrderService->getGoodsList($orderId);  //当前商品列表
        //goods_price 商品价格
        $nowRefundFee = 0;

        if($refundTypeClass==1){
            $RefundTypeText = "问题单处理:";
        }else{
            $RefundTypeText = "正常单处理:";
        }

        //获取工单类型
        $RefundTypeText .= $this->toolService->getRefundWorkTypeById($workType);

        //普通退款
        switch ($refundType){
            case "1":
                $RefundTypeText .= " [ 缺货退款 ] ";
                $RefundInfo = $RefundTypeText."「 ".$remark." 」<br/>";
                break;
            case "2":
                $RefundTypeText .= " [ 次品退款 ] ";
                $RefundInfo = $RefundTypeText."「 ".$remark." 」<br/>";
                break;
            case "3":
                $RefundTypeText .= " [ 退货退款 ] ";
                $RefundInfo = $RefundTypeText."「 ".$remark." 」<br/>";
                break;
            case "4":
                $RefundTypeText .= " [ 全单退款 ] ";
                $RefundInfo = $RefundTypeText."「 ".$remark." 」<br/>";

                $goodsList = DB::select("SELECT rec_id,goods_id,goods_sn,goods_name,goods_number-refund_number AS num FROM sdx_order_goods WHERE order_id = ".$orderId." AND goods_number>refund_number");
                $goodsList = json_decode(json_encode($goodsList),true);
                break;
            default:
                return "错误：不支持得退款类型";
        }



        //验证处理商品数是否有超过最大数😘😜

        foreach ($goodsList as $key=>$value){
            $thisGoodsNotFund = true;
            $thisGoodsPrice = 0;
            foreach ($goodsListNow as $value2){
                if($value['rec_id']==$value2['rec_id']){
                    if($value['num']>($value2['goods_number']-$value2['refund_number'])){
                        return "错误：「 ".$value['goods_name']." 」最大可操作数：".($value2['goods_number']-$value2['refund_number']);
                    }else{
                        $thisGoodsNotFund = false;
                        $thisGoodsPrice = $value2['goods_price'];
                        $goodsList[$key]['goods_id'] =  $value2['goods_id'];
                        $goodsList[$key]['remark'] =  "「 ".$value2['goods_name']." 」 退：".$value['num']." 份";
                        $goodsList[$key]['refundFee'] =  $value['num']*$thisGoodsPrice;
                        //$goodsList[$key]['giving'] =  $value2['giving'];
                    }
                }
            }
            if($thisGoodsNotFund){
                return "错误：「 ".$value['goods_name']." 」不在此订单内";
            }else{
                $RefundInfo .="「 ".$value['goods_name']." 」 退：".ceil($value['num'])." 份<br/>";
                $nowRefundFee += $value['num']*$thisGoodsPrice;
            }
        }

        if($shippingFee==true||$refundType==4){
            //加入运费
            $shippingFee=true;
            $nowRefundFee += $orderInfo['shipping_fee'];
            $RefundInfo .="已退运费：".$orderInfo['shipping_fee'];
        }

        //return $goodsList;
        Log::notice($orderId." to kindee data".json_encode($goodsList));

        $Kingdeeresult = $this->kindeeGoodsAction($orderId,$goodsList,$refundType,$this->toolService->getNameById($userId).":".$remark." 订单ID:".$orderId);
        if(is_array($Kingdeeresult)){
            if(empty($Kingdeeresult['Id'])){
                return "金蝶返回错误:".json_encode($Kingdeeresult);
            }
        }else{
            return "金蝶返回错误:".$Kingdeeresult;
        }

        //写入退款工单
        $refundWork = $this->penRefundWork($orderId,$orderInfo['order_sn'],$workType,$nowRefundFee,
            $RefundInfo,$userId,$wid,$this->toolService->getNameById($userId));

        if($refundWork>0){
            //处理订单退货数据
            $refundLogId = $this->penRefundLog($orderId,$orderInfo['order_sn'],$RefundTypeText,$nowRefundFee,
                $RefundInfo,$userId);
            if($refundLogId>0){
                Log::notice($orderId." to sdx data".json_encode($goodsList));
                foreach ($goodsList as $valueInfo){
                    //循环写入退款记录
                    if($valueInfo['giving']>0){
                        $valueInfo['goods_name'] .= "[ 赠品 ]";
                    }
                    $this->penRefundDetail($refundLogId,$orderId,$valueInfo['goods_id'],$valueInfo['goods_name'],
                        $valueInfo['goods_sn'],$valueInfo['rec_id'],$valueInfo['num'],$valueInfo['remark'],
                        $valueInfo['refundFee']);
                    //修改商品表
                    $this->updateOrderGoods($valueInfo['rec_id'],$valueInfo['num']);
                }

                //判断是否还有订单商品
                $existingGoodsList = $this->mainOrderService->getOrderGoodsListExisting($orderId);
                if(count($existingGoodsList)>0){
                    $payStatus = 3; //部分退款
                    $orderStatus = 5; //已分单
                }else{
                    $payStatus = 4; //全部退款
                    $orderStatus = 2; //已取消
                }
                $result = $this->updateOrder($orderId,$nowRefundFee,$orderStatus,$payStatus,$shippingFee);

                if($result==1){
                    //写入订单记录
                    $dataAction['order_status'] = $orderStatus;
                    $dataAction['shipping_status'] = $orderInfo['shipping_status'];
                    $dataAction['pay_status'] = $payStatus;
                    $dataAction['action_user'] = $this->toolService->getNameById($userId);
                    $dataAction['order_id']=$orderId;
                    $dataAction['action_note']=$RefundInfo." KingdeeSn:".$Kingdeeresult['Number'];
                    $dataAction['log_time']=gm_time();
                    $dataAction['user_id']=$userId;
                    $this->mainOrderService->addOrderAction($dataAction);
                    return true;
                }else{
                    return "错误：修改订单记录失败";
                }
            }else{
                return "错误：退款记录生成错误:1";
            }
        }else{
            return "错误：退款工单生成错误";
        }
    }

    /**
     * 推送金蝶退货处理
     * Author:poptser@foxmail.com
     * @param $orderId
     * @param $goodsList
     * @param $refundType
     * @param $note
     * @return mixed
     */
    public function kindeeGoodsAction($orderId, $goodsList, $refundType,$note){
        $KingdeeSn = Cache::get('orderKingdeeSn_'.$orderId);
        if(empty($KingdeeSn)){
            $KingdeeSn = DB::table("order_info")->where("order_id",$orderId)->value("k3cn_sn");
            Cache::put('orderKingdeeSn_'.$orderId,$KingdeeSn,1);
        }

        $goods = [];
        foreach ($goodsList as $item){
            $goods[] = [
                "goods_sn" =>$item['goods_sn'],
                "giving" =>$item['giving'],
                "op_number" =>$item['num'],
            ];
        }
        $refundData=[
            'FBillNo'=>$KingdeeSn,
            'goods'=>$goods,
            'note'=>$note
        ];
        Log::notice($orderId." in kindee data".json_encode($refundData));
        try{
            switch ($refundType){
                case "1":
                    //缺货
                    $result = $this->ConsignmentNoteService->UpdateConsignmentNoteAndMisDelivery($refundData);
                    break;
                case "2":
                    //次品退款
                    $result = $this->ConsignmentNoteService->UpdateConsignmentNoteAndDirectTransfers($refundData);
                    break;
                case "3":
                    //退货退款
                    $result = $this->ConsignmentNoteService->UpdateConsignmentNote($refundData);
                    break;
                case "4":
                    //全单退款
                    $result=$this->ConsignmentNoteService->UnAuditAndCancelConsignmentNote([$KingdeeSn]);
                    break;
            }
            return $result;
        }catch (\Exception $exception){
            //dump($exception->getMessage());
            return $exception->getMessage();
        }


    }
    /**
     * 更新订单记录
     * Author:poptser@foxmail.com
     * @param $orderId
     * @param $refundFee
     * @param $orderStatus
     * @param $payStatus
     * @param $shippingFee
     * @return mixed
     */
    public function updateOrder($orderId, $refundFee,$orderStatus,$payStatus,$shippingFee=null){
        if($shippingFee==true){
            //已退运费
            return DB::table('order_info')
                ->where('order_id', $orderId)
                ->increment('freeze_refund_amount', $refundFee,
                    [
                        'freeze_status'=>0,
                        'order_status'=>$orderStatus,
                        'is_refund_freight'=>1,
                        'pay_status'=>$payStatus
                    ]
                );
        }else{
            //未退运费
            return DB::table('order_info')
                ->where('order_id', $orderId)
                ->increment('freeze_refund_amount', $refundFee,
                    [
                        'freeze_status'=>0,
                        'order_status'=>$orderStatus,
                        'pay_status'=>$payStatus
                    ]
                );
        }

    }

    /**
     * 修改订单商品
     * Author:poptser@foxmail.com
     * @param $recId
     * @param $refundNumber
     * @return mixed
     */
    public function updateOrderGoods($recId, $refundNumber){
        DB::table('order_goods')
            ->where('rec_id', $recId)
            ->increment('refund_number', $refundNumber,['lackNum'=>0,'poorNum'=>0]);
    }
    /**
     * 写入退款详情
     * Author:poptser@foxmail.com
     * @param $refundLogId
     * @param $orderId
     * @param $goodsId
     * @param $goodsName
     * @param $goodsSn
     * @param $recId
     * @param $refundNumber
     * @param $remark
     * @param $refundFee
     * @return bool
     */
    public function penRefundDetail($refundLogId, $orderId, $goodsId, $goodsName, $goodsSn, $recId, $refundNumber,
                                    $remark, $refundFee){
        $refundId = DB::table('refund_detail')->insertGetId(
            [
                'log_id' => $refundLogId,   //退款记录ID
                'order_id' => $orderId,     //订单ID
                'goods_id' => $goodsId,     //商品ID
                'goods_name' => $goodsName, //商品名称
                'goods_sn' => $goodsSn,     //商品货号
                'order_goods_id' => $recId, //订单商品唯一
                'refund_number' => $refundNumber,   //退款数量
                'opt_time' => gm_time(),        //操作时间
                'opt_note' => $remark,          //备注
                'refund_amount' => $refundFee   //退款金额
            ]
        );
        if($refundId){
            return $refundId;
        }else{
            return false;
        }
    }

    /**
     * 写入退款记录主表
     * Author:poptser@foxmail.com
     * @param $orderId      //订单ID
     * @param $orderSn      //订单号
     * @param $refundType   //退款类型
     * @param $refundFee    //退款金额
     * @param $refundInfo   //退款描述
     * @param $userId   //
     * @return bool
     */
    public function penRefundLog($orderId, $orderSn, $refundType, $refundFee, $refundInfo,$userId){
        $refundId = DB::table('refund_log')->insertGetId(
            [
                'order_sn' => $orderSn,
                'order_id' => $orderId,
                'refund_type' => $refundType,
                'refund_amount' => $refundFee,
                'pay_name' => "等待退款",
                'admin_note' => $refundInfo,
                'admin_user' => $this->toolService->getNameById($userId),
                'refund_time' => gm_time(),
                'transid' => "等待退款"
            ]
        );
        if($refundId){
            return $refundId;
        }else{
            return false;
        }
    }

    /**
     * 工单写入
     * Author:poptser@foxmail.com
     * @param $orderId      //订单ID
     * @param $orderSn      //订单号
     * @param $refundType   //退款类型 1缺货 2次品
     * @param $refundFee    //退款金额
     * @param $refundInfo   //退款详细
     * @param $userId   //
     * @param $wid   //
     * @param $userName   //
     * @return mixed
     */
    public function penRefundWork($orderId, $orderSn, $refundType, $refundFee, $refundInfo,$userId,
                                    $wid,$userName){
        $refundId = DB::table('refund_work')->insertGetId(
            [
                'order_sn' => $orderSn,
                'order_id' => $orderId,
                'refund_type' => $refundType,
                'refund_fee' => $refundFee,
                'refund_info' => $refundInfo,
                'submit_time' => gm_time(),
                'submit_id' => $userId,
                'status' => 0,
                'wid' => $wid,
                'submit_name' => $userName
            ]
        );
        if($refundId){
            return $refundId;
        }else{
            return false;
        }
    }
}